﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.ActiveRecord;
using Castle.Components.Validator;

namespace Matriculex.Dominio
{
    [ActiveRecord("disciplina"), Serializable]
    public class Disciplina : RemovableEntityWithId<Disciplina>
    {
        // construtor vazio necessário para o ActiveRecord
        protected Disciplina() { }

        public Disciplina(string código, string nome)
        {
            this.Nome = nome;
            this.Código = código;
            this.Oferecimentos = new List<Oferecimento>();
            this.AlunosPreInscritos = new List<Aluno>();
            this.Cursos = new List<CursoAberto>();
        }


        public string NomeCompleto
        {
            get { return ToString(); }
        }

        [Property]
        [ValidateNonEmpty("Nome da Disciplina não pode ser vazio.")]
        public string Nome { get; set; }
        [Property]
        [ValidateNonEmpty("Código da Disciplina não pode ser vazio.")]
        public string Código { get; set; }
        private IList<Oferecimento> oferecimentos;
        [HasMany(Inverse=true)]
        public IList<Oferecimento> Oferecimentos
        {
            get
            {
                return new List<Oferecimento>(oferecimentos).AsReadOnly();
            }
            private set { oferecimentos = value; }
        }
        private IList<CursoAberto> cursos;
        [HasAndBelongsToMany(Table="curso_disciplina", ColumnKey="disciplina_id", ColumnRef="curso_id", Inverse=true)]
        public IList<CursoAberto> Cursos
        {
            get
            {
                return new List<CursoAberto>(cursos).AsReadOnly();
            }
            private set { cursos = value; }
        }

        public override string ToString()
        {
            return String.Format("{0} ({1})", this.Código, this.Nome);
        }

        private IList<Aluno> alunosPreInscritos;
        /// <summary>
        /// Obtém os alunos que selecionaram essa disciplina como parte do processo de inscrição no PECE.
        /// </summary>
        [HasAndBelongsToMany(Table = "disciplinas_aluno", ColumnKey = "disciplina_id", ColumnRef = "aluno_id", Inverse = true)]
        public IList<Aluno> AlunosPreInscritos
        {
            get
            {
                return new List<Aluno>(alunosPreInscritos).AsReadOnly();
            }
            private set { alunosPreInscritos = value; }
        }


        public override void Save()
        {
            Disciplina[] disciplinas = FindAllByProperty("Código", this.Código);
            // se é um novo curso
            if (this.IsTransient())
            {
                if (disciplinas != null && disciplinas.Length > 0)
                    throw new DominioException("Já existe uma disciplina com este código");
            }
            else
            {
                // se vamos salvar
                if (disciplinas != null && disciplinas.Length > 0)
                {
                    // se há mais de 1 curso com este código (inconsistencia)
                    // ou o Id do curso de código existen não é este
                    if (disciplinas.Length > 1 || disciplinas[0].Id != this.Id)
                        throw new DominioException("Já existe uma disciplina com este código");
                }
            }

            base.Save();
        }


    }
}
